/*
  	本插件依赖于七牛 &  ex-if.js
	注意——
    a、此第三方插件不需要第三方插件库文件 采用数据流二进制上传等方式
		自定义服务器上传 不依赖第三方库
    b、七牛全家桶
        1. 'upload_start_btn'没有被定义时，选择图片后会自动上传图片
        2. 获取token接口，qiniu_uptoken_url需要server重新提供，返回格式遵循TT协议约定，如：
            {
                "data": {
                    "uptoken": "0dBf-DK9byLfKLFrSxYdnCpocqBpLH1HUv0tb18t:tdMOJ8xkPjZxgBuEldB3ZjPV6JA=:eyJzY29wZSI6Im1haXpzc3MiLCJkZWFkbGluZSI6MTQ2ODM3NzM5MH0="
                    "domain": "http://7xpsli.com1.z0.glb.clouddn.com/"
                },
                "msg": "OK",
                "code": 0
            }
        3. 此七牛插件需要加载的js文件：
             开发环境——
                <script type="text/javascript" src="https://cdn.staticfile.org/Plupload/2.1.1/moxie.js"></script>
                <script type="text/javascript" src="https://cdn.staticfile.org/Plupload/2.1.1/plupload.dev.js"></script>
                <script type="text/javascript" src="https://cdn.staticfile.org/qiniu-js-sdk/1.0.14-beta/qiniu.js"></script>
             产品环境——
                <script type="text/javascript" src="https://cdn.staticfile.org/plupload/3.0-beta1/plupload.min.js"></script>
                <script type="text/javascript" src="https://cdn.staticfile.org/qiniu-js-sdk/1.0.14-beta/qiniu.min.js"></script>
*/
(function() {
    var qiuwebApi = {

        //初始化默认值
        params: {
            upload_btn: 'upload-btn',
            upload_start_btn: 'upload-begin',
            upload_wrap: 'upload-wrap',
            max_width: 720,
            quality: 50,
            zoom: 2,
            orientation: 0,
            capture: 1,
            upload_url: 'http://upload.qiniu.com/' || 'http://192.168.8.15:3000/upload/myinfo/pic'
        },
        //初始化参数数据结构
        init: function() {

            var self = this;
            self.params = this.params
            self.path = []
            self.name = []
            self.max_width = self.params.max_width ? self.params.max_width : 720;
            self.max_height = self.max_width * 2;
            self.uptoken = self.params.uptoken ? self.params.uptoken : 'i8m3lz89N5AGghEJC5n_cFIZ9QamW4U28Oxgdj7r:uy8i4LY2rVpn3hccpe4myKfN-24=:eyJzY29wZSI6ImdhLWFsYnVtIiwiZGVhZGxpbmUiOjE0ODczNDc2NTd9';
            self.qiniu_domain = self.params.domain ? self.params.domain : 'https://ga-album-cdnqn.52tt.com/';
            self.base64 = []

            switch (self.params.orientation) {
                case 0:
                    self.fileUpload();
                    break;
                case 1:
                    self.fileQiniu();
                    break;
                default:
                    self.fileUpload();
                    break;
            }

        },
        //自定义根据id生成input[type:file]
        creatDom: function(callback) {

            var self = this;
            //创建需要的dom元素
            var buttonsHTML = '';
            var _modalTemplateTempDiv = document.createElement('div');
            var hash = _.uniqueId('contact_'); //生成唯一的标志
            var _width = $$('#' + self.params.upload_btn).width();
            var _height = $$('#' + self.params.upload_btn).height();
            var _left = Math.abs($$('#' + self.params.upload_btn).offset().left - $$('#' + self.params.upload_wrap).offset().left); //获取父元素左差
            var _top = Math.abs($$('#' + self.params.upload_btn).offset().top - $$('#' + self.params.upload_wrap).offset().top); //获取父元素高差

            //设置div 属性
            var creatDiv_id = self.params.html5_container = 'html5_' + hash + '_container';
            var creatDiv_style = 'position: absolute;top: ' + _top + 'px;left: ' + _left + 'px;width: ' + _width + 'px;height:' + _height + 'px;overflow: hidden; z-index: 2';

            //设置input file文件上传
            var creatInput_id = self.params.input_container = 'html5_' + hash;
            var creatInput_class = 'moxie-shim moxie-shim-html5';
            var creatInput_style = 'font-size: 999px; opacity: 0; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;'
            var creatInput_accept = 'image/jpeg,image/gif,image/png,image/*';
            var creatInput_type = 'file';

            //设置全局的id属性值
            buttonsHTML += '<div id="' + creatDiv_id + '" class="' + creatInput_class + '" style="' + creatDiv_style + '">';
            buttonsHTML += '<input id="' + creatInput_id + '" name="' + creatInput_type + '" type="' + creatInput_type + '" style="' + creatInput_style + '" accept="' + creatInput_accept + '" '
            buttonsHTML += (self.params.capture == 1 ? 'capture="camera"' : '') + (self.params.multi_selection ? multiple = "multiple" : "") + '>';
            buttonsHTML += '</div>';

            //挂载html元素等
            _modalTemplateTempDiv.innerHTML = buttonsHTML;
            var modal = $$(_modalTemplateTempDiv).children();
            $$('#' + self.params.upload_wrap).append(modal[0]).html();

            //挂载监听input输入框的change事件
            $$('#' + creatInput_id).on('change', function(val) {
                var files = val.currentTarget.files;
                //生成base64预览图
                $$.each(files, function(index, val) {
                    self.readFile(val, function(data) {
                        self.params.readFileFunc && self.params.readFileFunc(data);
                        // self.base64ToArrayBuffer(data)
                        self.base64.push(data)
                            //上传之后迭代依次上传图片
                        if (callback && files.length == self.base64.length) callback()
                    })
                })
            })
        },
        //独立上传 不依赖第三方插件
        fileUpload: function() {
            var self = this;
            var base64ToArrayUpload = function() {
                    $$.each(self.base64, function(index, val) {
                        //利用formdata上传函数
                        myApp.showLoadingIndicator();
                        var blob = self.base64ToArrayBuffer(val, 'image/jpeg', true);
                        var fd = new FormData();
                        fd.append('filename', self.name);
                        fd.append('file', blob);
                        fd.append('token', self.uptoken);
                        fd.append('unique_names', true);
                        var xhr = new XMLHttpRequest();
                        xhr.addEventListener("load", function(data) {
                            var rs = _.isString(data.currentTarget.response) ?
                                JSON.parse(data.currentTarget.response) : data.currentTarget.response
                            self.path.push(self.qiniu_domain + rs.key)
                            self.params.uploadedFunc(self.path);
                            self.path = []
                            myApp.hideLoadingIndicator();
                            //console.log(data)
                        }, false);
                        xhr.addEventListener("error", function(err) {
                            console.log(err)
                        }, false);
                        xhr.open("POST", self.params.upload_url);
                        xhr.send(fd);
                    })
                }
                //生成dom input file等
            self.creatDom(base64ToArrayUpload);
        },
        //加载七牛上传api插件
        fileQiniu: function() {
            var self = this;
            self.uploader = Qiniu.uploader({ //7牛自带的api方法类
                runtimes: 'html5,flash,html4',
                browse_button: self.params.upload_btn,
                container: self.params.upload_wrap,
                drop_element: self.params.upload_wrap,
                max_file_size: '200mb',
                flash_swf_url: self.params.flash_swf_url ? self.params.flash_swf_url : 'http://cdn.staticfile.org/Plupload/2.1.1/Moxie.swf',
                dragdrop: true,
                chunk_size: '4mb',
                multi_selection: !(mOxie.Env.OS.toLowerCase() === "ios" && mOxie.Env.version <= 7) && self.params.multi_selection, //ios7以下 不能多选图片
                uptoken: self.uptoken,
                domain: self.qiniu_domain,
                get_new_uptoken: false,
                unique_names: true,
                auto_start: $$('#' + self.params.upload_start_btn).length ? false : true,
                log_level: 0,
                filters: {
                    mime_types: [ //只允许上传图片和zip文件
                        {
                            title: "Image files",
                            extensions: "jpg,jpeg,gif,png"
                        },
                    ],
                    // max_file_size : '800kb', //最大只能上传800kb的文件
                    prevent_duplicates: true //不允许选取重复文件
                },
                resize: {
                    width: self.max_width,
                    height: self.max_height,
                    quality: 90,
                    preserve_headers: false
                },
                init: {
                    'FilesAdded': function(up, files) {
                        files.forEach(function(val) {
                            self.readFile(val.getNative(), function(data) {
                                self.params.readFileFunc && self.params.readFileFunc(data);
                            })
                        });
                        if (!$$('#' + self.params.upload_start_btn).length) self.uploader.start()
                    },
                    'BeforeUpload': function(up, file) {
                        if (!$$('.preloader').length) {
                            myApp.showIndicator();
                        }
                    },
                    'UploadProgress': function(up, file) {},
                    'UploadComplete': function() {},
                    'FileUploaded': function(up, file, info) {
                        var info = JSON.parse(info);
                        var key = info.key;
                        var name = file.name;
                        self.path.push(self.qiniu_domain + key)
                        self.name.push(name)
                            // console.log('上传中：'+ up.total.uploaded +'/'+up.files.length);
                            // console.log(up.files[up.files.length-1].status);
                            //&& self.path.length == up.files.length
                        if (up.files[up.files.length - 1].status === 5) {
                            // console.log('上传中：'+ up.files.length +'/'+up.files.length);
                            // console.log('上传完毕');
                            if (self.params.uploadedFunc) {
                                self.params.uploadedFunc(self.path);
                                self.path = []
                            }
                            myApp.hideIndicator();
                        }
                    },
                    'Error': function(up, err, errTip) {}
                }
            });
            //自定义加载完毕之后定义上传input 的样式
            setTimeout(function() {
                $$('.moxie-shim').css('z-index', 2);
            }, 100);
            if (self.params.capture == 1) $$('.moxie-shim>input').attr('capture', 'camera');
            //给按钮添加事件
            $$('#' + self.params.upload_start_btn).on('click', function() {
                self.uploader.start()
            })
        },
        //读取图片文件
        readFile: function(file, successFunc) {
            var self = this
                //如果不是图片就返回
            if (!/image\/\w+/.test(file.type)) {
                myApp.alert("请确保文件为图像类型");
                return false;
            }

            self.name = file.name

            var objURL = URL.createObjectURL(file);
            var reader = new FileReader();
            reader.readAsDataURL(file);

            reader.onload = function(e) {
                // successFunc && successFunc(e.currentTarget.result);
                // 生成略缩图，暂无必要
                var image_dom = new Image();
                image_dom.src = e.currentTarget.result;

                image_dom.onload = function() {

                    var orientation = self.exifOrientation(self.base64ToArrayBuffer(image_dom.src, 'image/jpeg'))
                        //successFunc && successFunc(e.currentTarget.result);
                        // if (image_dom.width >= self.max_width || orientation > 1) {
                        //     //successFunc && successFunc(self.canvasToCompressBase64(image_dom));
                        //     successFunc && successFunc(self.fixOrientation(orientation, image_dom));
                        // } else {
                        //     // successFunc && successFunc(image_dom.src);
                        //     successFunc && successFunc(self.fixOrientation(orientation, image_dom));
                        // }
                    successFunc && successFunc(self.fixOrientation(orientation, image_dom));
                }
            }
        },
        //设置布尔值获取base64二进制数据流
        base64ToArrayBuffer: function(base64, contentType, atobType) {
            contentType = contentType || base64.match(/^data\:([^\;]+)\;base64,/mi)[1] || ''; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg'
            base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '');
            var self = this;
            var binary = atob(base64);
            var len = binary.length;
            var buffer = new ArrayBuffer(len);
            var view = new Uint8Array(buffer);
            for (var i = 0; i < len; i++) {
                view[i] = binary.charCodeAt(i);
            }
            //canvas.toDataURL 返回的默认格式就是 image/png
            if (atobType) {
                var blob = new Blob([view], {
                    type: contentType
                });
                return blob
            } else {
                return buffer;
            }
        },
        //返回拍摄照片的枚举 依赖于 exif-js 识别ios照片的方向
        exifOrientation: function(binFile) {
            // extract orientation information from the image provided by iOS
            var dataView = new DataView(binFile);
            if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
                console.log('Not a valid JPEG file');
                return 0;
            }
            var offset = 2;
            var marker = null;
            while (offset < binFile.byteLength) {
                // find 0xFFE1 (225 marker)
                if (dataView.getUint8(offset) != 0xFF) {
                    console.log('Not a valid marker at offset ' + offset + ', found: ' + dataView.getUint8(offset));
                    return 0;
                }
                marker = dataView.getUint8(offset + 1);
                if (marker == 225) {
                    offset += 4;
                    var str = "";
                    for (n = 0; n < 4; n++) {
                        str += String.fromCharCode(dataView.getUint8(offset + n));
                    }
                    if (str != 'Exif') {
                        console.log('Not valid EXIF data found');
                        return 0;
                    }

                    offset += 6; // tiffOffset
                    var bigEnd = null;

                    // test for TIFF validity and endianness
                    if (dataView.getUint16(offset) == 0x4949) {
                        bigEnd = false;
                    } else if (dataView.getUint16(offset) == 0x4D4D) {
                        bigEnd = true;
                    } else {
                        console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
                        return 0;
                    }

                    if (dataView.getUint16(offset + 2, !bigEnd) != 0x002A) {
                        console.log("Not valid TIFF data! (no 0x002A)");
                        return 0;
                    }

                    var firstIFDOffset = dataView.getUint32(offset + 4, !bigEnd);
                    if (firstIFDOffset < 0x00000008) {
                        console.log("Not valid TIFF data! (First offset less than 8)", dataView.getUint32(offset + 4, !bigEnd));
                        return 0;
                    }

                    // extract orientation data
                    var dataStart = offset + firstIFDOffset;
                    var entries = dataView.getUint16(dataStart, !bigEnd);
                    for (var i = 0; i < entries; i++) {
                        var entryOffset = dataStart + i * 12 + 2;
                        if (dataView.getUint16(entryOffset, !bigEnd) == 0x0112) {
                            var valueType = dataView.getUint16(entryOffset + 2, !bigEnd);
                            var numValues = dataView.getUint32(entryOffset + 4, !bigEnd);
                            if (valueType != 3 && numValues != 1) {
                                console.log('Invalid EXIF orientation value type (' + valueType + ') or count (' + numValues + ')');
                                return 0;
                            }
                            var value = dataView.getUint16(entryOffset + 8, !bigEnd);
                            if (value < 1 || value > 8) {
                                console.log('Invalid EXIF orientation value (' + value + ')');
                                return 0;
                            }
                            return value;
                        }
                    }
                } else {
                    offset += 2 + dataView.getUint16(offset + 2);
                }
            }
            return 0;
        },
        //通过canvas压缩预览图片
        fixOrientation: function(orientation, img) {
            // fix image orientation based on exif orientation data
            // exif orientation information
            //    http://www.impulseadventure.com/photo/exif-orientation.html
            //    link source wikipedia (https://en.wikipedia.org/wiki/Exif#cite_note-20)
            var self = this;
            var canvas = document.createElement("canvas");
            var compress_size = self.params.max_width;

            var ctx = canvas.getContext("2d");
            var h = img.height / self.params.zoom;
            // var h = (img.height/img.width)/self.params.zoom;
            var t = img.width / self.params.zoom;

            // switch width height if orientation needed
            canvas.width = t;
            canvas.height = h;

            // transform (rotate) image - see link at beginning this method
            switch (orientation) {
                case 2:
                    ctx.transform(-1, 0, 0, 1, canvas.width, 0);
                    break;
                case 3:
                    ctx.transform(-1, 0, 0, -1, canvas.width, canvas.height);
                    break;
                case 4:
                    ctx.transform(1, 0, 0, -1, 0, canvas.height);
                    break;
                case 5:
                    ctx.transform(0, 1, 1, 0, 0, 0);
                    break;
                case 6:
                    ctx.transform(0, 1, -1, 0, canvas.height, 0);
                    break;
                case 7:
                    ctx.transform(0, -1, -1, 0, canvas.height, canvas.width);
                    break;
                case 8:
                    ctx.transform(0, -1, 1, 0, 0, canvas.width);
                    break;
            }

            ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
            // pass rotated image data to the target image container
            //image/jpeg’, quality/100
            //console.log(self)
            return canvas.toDataURL("image/jpeg", self.quality / 100);
        },
        set: function() {
            // set one or more params
            // variable argument list: 1 param = hash, 2 params = key, value
            if (arguments.length == 1) {
                for (var key in arguments[0]) {
                    this.params[key] = arguments[0][key];
                }
                //_.extend(this.params, arguments[0]);
            } else {
                this.params[arguments[0]] = arguments[1];
            }
            this.init()
        }
    }

    // qiuwebApi.init();

    if (typeof define === 'function' && define.amd) {
        define(function() { return qiuwebApi; });
    } else if (typeof module === 'object' && module.exports) {
        module.exports = qiuwebApi;
    } else {
        window.qiuwebApi = qiuwebApi;
    }
})(window)